package me.helllp.dake.generator.engine;

import freemarker.template.TemplateException;
import lombok.Getter;
import lombok.Setter;
import me.helllp.dake.common.anno.MataGenerator;
import me.helllp.dake.generator.config.GeneratorEngineConfiguration;
import me.helllp.dake.generator.engine.mybatis.MapperGenerator;
import me.helllp.dake.generator.engine.mybatis.PoGenerator;
import me.helllp.dake.generator.engine.mybatis.XmlGenerator;
import me.helllp.dake.generator.meta.IThirdComponent;
import me.helllp.dake.generator.meta.ProjectMetaData;
import me.helllp.dake.generator.meta.third.RdbmsMetaData;
import me.helllp.dake.generator.sql.DbMateData;
import me.helllp.dake.generator.sql.api.IntrospectedTable;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * 数据库相关操作的生成器
 */
@Getter
@Setter
public class RdbmsGenerator extends AbstractGenerator {
    @MataGenerator
    private ProjectMetaData projectMetaData;

    /**
     * 数据表的信息
     */
    @MataGenerator
    private List<IntrospectedTable> tables;

    public RdbmsGenerator(ProjectMetaData projectMetaData) {
        this.projectMetaData = projectMetaData;
    }

    @Override
    public void initGenerator(GeneratorEngineConfiguration engineConfiguration) throws TemplateException, IOException, InvocationTargetException, IllegalAccessException {
        super.initGenerator(engineConfiguration);
    }

    @Override
    public void generator() throws IOException, TemplateException, InvocationTargetException, IllegalAccessException {
        IThirdComponent component = Optional.ofNullable(projectMetaData.getThirdComponents()).orElse(Collections.emptyList())
                .stream().filter(data -> data instanceof RdbmsMetaData).findFirst().get();

        DbMateData dbMateData = new DbMateData((RdbmsMetaData)component);
        try {
            tables = dbMateData.getTablesInfo();
        } catch (SQLException | InterruptedException e) {
            throw new RuntimeException(e);
        }

        PoGenerator poGenerator = new PoGenerator(projectMetaData);
        MapperGenerator mapperGenerator = new MapperGenerator(projectMetaData);
        XmlGenerator xmlGenerator = new XmlGenerator(projectMetaData);

        poGenerator.initGenerator(getEngineConfiguration());
        mapperGenerator.initGenerator(getEngineConfiguration());
        xmlGenerator.initGenerator(getEngineConfiguration());

        poGenerator.setTables(tables);
        mapperGenerator.setTables(tables);
        xmlGenerator.setTables(tables);

        poGenerator.generator();
        mapperGenerator.generator();
        xmlGenerator.generator();
    }
}
